// 现代 JavaScript 类和继承
// 作者：AI助手
// 最后更新：2024年

/**
 * ES6 类语法提供了更清晰、更面向对象的方式来创建对象和实现继承
 * 特点：
 * 1. class 语法
 * 2. 构造函数
 * 3. 实例方法和静态方法
 * 4. getter/setter
 * 5. 继承
 * 6. 私有字段（#）
 */

// 1. 基本类定义
class Person {
    // 1.1 构造函数
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    // 1.2 实例方法
    sayHello() {
        console.log(`你好，我是 ${this.name}，今年 ${this.age} 岁`);
    }

    // 1.3 getter/setter
    get info() {
        return `${this.name}-${this.age}`;
    }

    set info(value) {
        [this.name, this.age] = value.split('-');
    }

    // 1.4 静态方法
    static createAnonymous() {
        return new Person('匿名', 0);
    }
}

// 2. 类的使用
const person1 = new Person('张三', 25);
person1.sayHello();
console.log(person1.info);
person1.info = '李四-30';
person1.sayHello();

// 3. 继承
class Student extends Person {
    constructor(name, age, grade) {
        // 调用父类构造函数
        super(name, age);
        this.grade = grade;
    }

    study() {
        console.log(`${this.name} 正在学习`);
    }

    // 重写父类方法
    sayHello() {
        super.sayHello(); // 调用父类方法
        console.log(`我是 ${this.grade} 年级的学生`);
    }
}

const student1 = new Student('小明', 15, '初三');
student1.sayHello();
student1.study();

// 4. 私有字段和方法
class BankAccount {
    // 私有字段声明
    #balance = 0;
    #transactions = [];

    constructor(initialBalance) {
        this.#balance = initialBalance;
    }

    // 私有方法
    #validateAmount(amount) {
        return amount > 0 && Number.isFinite(amount);
    }

    deposit(amount) {
        if (this.#validateAmount(amount)) {
            this.#balance += amount;
            this.#transactions.push({ type: 'deposit', amount });
            return true;
        }
        return false;
    }

    withdraw(amount) {
        if (this.#validateAmount(amount) && this.#balance >= amount) {
            this.#balance -= amount;
            this.#transactions.push({ type: 'withdraw', amount });
            return true;
        }
        return false;
    }

    get balance() {
        return this.#balance;
    }

    get transactionHistory() {
        return [...this.#transactions];
    }
}

// 5. 实际应用示例
// 5.1 组件类
class Component {
    constructor(id) {
        this.element = document.getElementById(id);
    }

    hide() {
        this.element.style.display = 'none';
    }

    show() {
        this.element.style.display = 'block';
    }
}

// 5.2 特定组件
class Modal extends Component {
    #isOpen = false;

    constructor(id) {
        super(id);
        this.#addEventListeners();
    }

    #addEventListeners() {
        // 私有方法处理事件绑定
    }

    open() {
        this.show();
        this.#isOpen = true;
    }

    close() {
        this.hide();
        this.#isOpen = false;
    }
}

// 6. Mixin 模式
// 通过混入添加功能
const LoggerMixin = {
    log(message) {
        console.log(`[${this.constructor.name}]: ${message}`);
    }
};

// 使用 Mixin
Object.assign(Person.prototype, LoggerMixin);
const person2 = new Person('王五', 35);
person2.log('测试日志');

// 7. 最佳实践
// ✅ 使用类字段初始化属性
class Product {
    name = '';
    price = 0;
    category = 'default';

    constructor(name, price) {
        this.name = name;
        this.price = price;
    }
}

// ✅ 使用私有字段保护数据
class User {
    #password;
    
    setPassword(pwd) {
        this.#password = pwd;
    }
    
    validatePassword(pwd) {
        return this.#password === pwd;
    }
}

// ❌ 避免在构造函数中返回值
// class Wrong {
//     constructor() {
//         return {}; // 不要这样做
//     }
// }

// ❌ 避免在构造函数中使用异步操作
// class AsyncWrong {
//     async constructor() { // 语法错误
//         await someAsyncOperation();
//     }
// } 